package pwd.allen.controller;

import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import pwd.allen.service.IHelloService;

import javax.servlet.http.HttpServletRequest;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 线程打印
 *
 * @author lenovo
 * @create 2019-10-06 9:35
 **/
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@RestController
public class ThreadController {

//    @Autowired
    @DubboReference(version = "pwd-1.0", loadbalance = "random", timeout = 1000, stub="pwd.allen.service.stub.HelloServiceStub")
    private IHelloService helloService;

    @GetMapping("/getThread/{type}")
    public Object getThread(HttpServletRequest request, @PathVariable String type) {

        String action = request.getParameter("action");
        String excludes = request.getParameter("excludes");
        String includes = request.getParameter("includes");
        Long id = null;
        try {
            id = Long.parseLong(request.getParameter("id"));
        } catch (NumberFormatException e) {}
        Integer top = null;
        try {
            top = Integer.parseInt(request.getParameter("top"));
        } catch (NumberFormatException e) {}
        if ("test".equals(action)) {
            new Thread(new MyRunnable(), "pwd-thread").start();
            return "启动线程";
        }
        if ("service".equals(type)) {
            return helloService.getThread(action, id, excludes, includes, top);
        }
        return getThread(action, id, excludes, includes, top);
    }

    /**
     * 打印线程信息
     * @param action
     * @param id
     * @return
     */
    public Object getThread(String action, Long id, String excludes, String includes, Integer top) {

        // 获取java线程管理器MXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

        List<ThreadInfo> threadInfoList = new ArrayList<ThreadInfo>();

        if (id != null) {
            ThreadInfo threadInfo = threadMXBean.getThreadInfo(id);
            if (threadInfo != null) {
                threadInfoList.add(threadInfo);
            }
        } else {
            //  lockedMonitors参数表示是否获取同步的monitor信息，lockedSynchronizers表示是否获取同步的synchronizer
            ThreadInfo[] infos = threadMXBean.dumpAllThreads(false,false);

            if (includes != null) {
                for (ThreadInfo info : infos) {
                    boolean ifInclude = false;
                    for (String include : includes.split(",")) {
                        if (info.getThreadName().startsWith(include)) {
                            ifInclude = true;
                            break;
                        }
                    }
                    if (ifInclude) {
                        threadInfoList.add(info);
                    }
                }
            } else if (excludes != null) {
                for (ThreadInfo info : infos) {
                    boolean ifExclude = false;
                    for (String exclude : excludes.split(",")) {
                        if (info.getThreadName().startsWith(exclude)) {
                            ifExclude = true;
                            break;
                        }
                    }
                    if (ifExclude) {
                        continue;
                    }
                    threadInfoList.add(info);
                }
            } else {
                threadInfoList.addAll(Arrays.asList(infos));
            }
        }

        if (top != null && top < threadInfoList.size()) {
            threadInfoList = threadInfoList.subList(0, top);
        }

        if ("all".equals(action)) {
            return JSON.toJSON(threadInfoList);
        }
        List<Map> list = new ArrayList<Map>();
        for (ThreadInfo info : threadInfoList) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("threadId", info.getThreadId());
            map.put("threadName", info.getThreadName());
            map.put("lockName", info.getLockName());
            list.add(map);
        }
        return JSON.toJSON(list);
    }

    class MyRunnable implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(60000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
